package com.lzh.runke.core.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lzh.runke.core.web_base.exception.BusinessException;
import com.lzh.runke.core.entity.FileInfo;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 文件工具类 用于获取对象中 文件类型对象的文件名
 * @Author: LiuZiHao
 * @Date: 2022/5/26 16:50
 */
public class FileUtil {

    private FileUtil() {
    }

    private static final String JSON_NODE_TYPE_NAME = "com.fasterxml.jackson.databind.JsonNode";
    private static final String FILE_INFO_TYPE_NAME = "com.rkinf.framework.file.entity.FileInfo";
    private static final String LIST_FILE_INFO_TYPE_NAME = "java.util.List<com.rkinf.framework.file.entity.FileInfo>";
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 从实体中获取fileNames
     * 获得实体类中的 FileInfo;List<FileInfo>;JsonNode的fileName
     *
     * @param entity
     * @param <T>
     * @return filenameList
     */
    public static <T> List<String> getFilenames(T entity) {
        List<String> filenames = new ArrayList<>();
        List<Field> declaredFields = getAllField(entity);
        for (Field field : declaredFields) {
            //String typeName = field.getGenericType().getTypeName();
            //String typeName2 = field.getType().getTypeName();
            //1.首先是返回的类型不一样，一个是Class对象一个是Type接口。
            //2.如果属性是一个泛型，从getType（）只能得到这个属性的接口类型。但从getGenericType（）还能得到这个泛型的参数类型。
            //3.getGenericType（）如果当前属性有签名属性类型就返回，否则就返回 Field.getType()。
            //System.out.println("getGenericType() : " + typeName);
            //System.out.println("getType() : " + typeName2);

            if (field.getGenericType().getTypeName().equals(FILE_INFO_TYPE_NAME)) {
                field.setAccessible(true);
                try {
                    Object o = field.get(entity);
                    if (!ObjectUtils.isEmpty(o) && o instanceof FileInfo && !ObjectUtils.isEmpty(((FileInfo) o).getFilename())) {
                        String filename = ((FileInfo) o).getFilename();
                        filenames.add(filename);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    throw new BusinessException("保存文件错误，请重试");
                }
            }

            if (field.getGenericType().getTypeName().equals(LIST_FILE_INFO_TYPE_NAME)) {
                field.setAccessible(true);
                try {
                    Object o = field.get(entity);
                    if (!ObjectUtils.isEmpty(o) && o instanceof List<?>) {
                        List<?> list = (List<?>) o;
                        if (!CollectionUtils.isEmpty(list)) {
                            for (Object o1 : list) {
                                if (o1 instanceof FileInfo) {
                                    filenames.add(((FileInfo) o1).getFilename());
                                }
                            }
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    throw new BusinessException("保存文件错误，请重试");
                }
            }

            if (field.getGenericType().getTypeName().equals(JSON_NODE_TYPE_NAME)) {
                field.setAccessible(true);
                try {
                    Object o = field.get(entity);
                    if (!ObjectUtils.isEmpty(o) && o instanceof JsonNode) {
                        JsonNode jsonNode = (JsonNode) o;
                        JsonNode fileNameJsonNode = jsonNode.get("filename");
                        if (!ObjectUtils.isEmpty(fileNameJsonNode)) {
                            String fileName = MAPPER.treeToValue(fileNameJsonNode, String.class);
                            filenames.add(fileName);
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    throw new BusinessException("保存文件错误，请重试");
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                    throw new BusinessException("保存文件时json处理异常");
                }
            }
        }
        return filenames;
    }


    private static <T> List<Field> getAllField(T entity) {
        Class<?> clazz = entity.getClass();
        List<Field> fields = new ArrayList<>();
        while (clazz != null) {
            fields.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

    public static void main(String[] args) throws JsonProcessingException {
//        FileInfo fileInfo = new FileInfo();
//        fileInfo.setFilename("test");
//        LandAccessEntity entity = new LandAccessEntity();
//        String jsonS = "{\n" +
//                "                \"filename\":\"testname\",\n" +
//                "                \"originalName\":\"原始文件名字\"\n" +
//                "                }\n";
//        //JSON ----> JsonNode
//        ObjectMapper mapper = new ObjectMapper();
//        JsonNode jsonNode = mapper.readTree(jsonS);
//        entity.setTest(fileInfo);
//        entity.setTestList(new ArrayList<>(Arrays.asList(fileInfo, fileInfo)));
//        entity.setBoundaryFile(jsonNode);
//        List<String> filenames = FileUtil.getFilenames(entity);
//        for (String filename : filenames) {
//            System.out.println(filename);
//        }
    }
}
